﻿using System.Collections.Generic;
using Cms.Domain;
using Cms.Domain.RepositoryInterfaces;
using NHibernate;
using NHibernate.Criterion;

namespace Cms.Data
{
    public class AdministratorRepository : BaseRepository, IAdministratorRepository
    {
        public AdministratorRepository()
        {
        }
        
        public AdministratorRepository(ISession session)
            : base(session)
        {
        }

        #region IAdministratorRepository Members

        public Administrator GetAdministrator(int id)
        {
            return Session.Get<Administrator>(id);
        }

        public Administrator GetAdministrator(string username, string password)
        {
            string hql = "from Administrator where Username = :username and Password = :password";
            IList<Administrator> admins = Session.CreateQuery(hql)
                .SetString("username", username)
                .SetString("password", password)
                .SetCacheable(true)
                .List<Administrator>();
            return admins.Count == 1 ? admins[0] : null;
        }

        public void SaveAdministrator(Administrator administrator)
        {
            SaveEntity(administrator, "AdministratorRepository.SaveAdministrator");
        }
        
        public IList<AdministratorGroup> GetGroups()
        {
            return Session.CreateCriteria(typeof(AdministratorGroup))
                .AddOrder(NHibernate.Criterion.Order.Asc("Name"))
                .SetCacheable(true)
                .List<AdministratorGroup>();
        }
        
        public IList<AdministratorGroup> GetCustomGroups()
        {
            return Session.CreateCriteria(typeof(AdministratorGroup))
                .Add(Restrictions.Not(Restrictions.Eq("ID", 1)))
                .AddOrder(NHibernate.Criterion.Order.Asc("Name"))
                .SetCacheable(true)
                .List<AdministratorGroup>();
        }

        public IList<Administrator> GetAdministrators()
        {
            return Session.CreateCriteria(typeof(Administrator))
                .Add(Restrictions.Not(Restrictions.Eq("Deleted", true)))
                .AddOrder(NHibernate.Criterion.Order.Asc("Firstname"))
                .AddOrder(NHibernate.Criterion.Order.Asc("Lastname"))
                .SetCacheable(true)
                .List<Administrator>();
        }
        
        public AdministratorGroup GetGroup(int id)
        {
            return Session.Get<AdministratorGroup>(id);
        }
        
        public void SaveGroup(AdministratorGroup group)
        {
            SaveEntity(group, "AdministratorRepository.SaveGroup");
        }
        
        public void DeleteGroup(int id)
        {
            DeleteHql("from AdministratorGroup where Id = " + id, "AdministratorRepository.DeleteGroup");
        }
        
        public void DeleteAdministrator(int id)
        {
            DeleteHql("from Administrator where Id = " + id, "AdministratorRepository.DeleteAdministrator");
        }
        
        public bool UsernameExists(string username, int id)
        {
            string hql = "from Administrator a where a.Username = :username";
            if (id > 0)
                hql += " and a.ID <> " + id;
            IList<Administrator> administrators = Session.CreateQuery(hql)
                .SetString("username", username)
                .List<Administrator>();
            return administrators.Count > 0;
        }

        #endregion
    }
}